﻿using System.Collections;
using System.Collections.Generic;
using System;

public class Schedule
{

    public static Schedule instance_;
	public static Schedule instance
    {
        get {
            if (instance_ == null)
            {
                instance_ = new Schedule();
            }
            return instance_;
        }
    }
    List<Scheduer> acheduerList = new List<Scheduer>();

    public void AddUpdater(Action action)
    {
        acheduerList.Add(new Scheduer(SchedueType.Updater,action));
    }

    public void RemoveActioner(Action action)
    {
        for (int i = acheduerList.Count-1; i >=0; i--)
        {
            if (acheduerList[i].action == action)
            {
                acheduerList.RemoveAt(i);
                break;
            }
        }
    }

    public void AddTimer(float delay,bool isLoop,Action action)
    {
        acheduerList.Add(new Scheduer(SchedueType.Timer, action, time:delay));
    }

    public void AddFramer(int frame, bool isLoop, Action action)
    {
        acheduerList.Add(new Scheduer(SchedueType.Framer, action, isLoop, frame: frame));
    }

    public void Update (float delta)
    {
        for (int i = acheduerList.Count - 1; i >= 0; i--)
        {
            Scheduer sder = acheduerList[i];
            switch (sder.st)
            {
                case SchedueType.Framer:
                    if (sder.framer < sder.frame)
                    {
                        sder.framer++;
                    }
                    else
                    {
                        sder.DoAction();
                        if (sder.isLoop)
                        {
                            sder.framer = 0;
                        }
                        else
                        {
                            acheduerList.RemoveAt(i);
                        }
                    }
                    break;
                case SchedueType.Timer:
                    if (sder.timer < sder.time)
                    {
                        sder.timer += delta;
                    }
                    else
                    {
                        sder.DoAction();
                        if (sder.isLoop)
                        {
                            sder.timer = 0;
                        }
                        else
                        {
                            acheduerList.RemoveAt(i);
                        }
                    }
                    break;
                case SchedueType.Updater:
                    sder.DoAction();
                    break;
            }
        }
    }
}

class Scheduer
{
    public Scheduer(SchedueType st,Action action, bool isLoop = false,float time = 0f,int frame=1)
    {
        this.st = st;
        this.action = action;
        this.isLoop = isLoop;
        this.time = time;
        this.frame = frame;
    }

    public SchedueType st;
    public Action action;
    public bool isLoop;
    public float time;
    public int frame;
    public float timer;
    public int framer;
    public void DoAction()
    {
        if (action != null)
        {
            action();
        }
    }
}
enum SchedueType
{
    Updater,
    Timer,
    Framer
}